<?php

namespace app\api\Logic\Online;

use app\api\model\OnlineVideoModel;
use app\api\model\OnlineVideoOrderModel;
use app\api\model\PayLogModel;
use think\Db;
use think\db\exception\DataNotFoundException;
use think\db\exception\ModelNotFoundException;
use think\Exception;
use think\exception\DbException;

class OnlineVideoOrderLogic
{
    /**
     * 验证用户是否允许报名/下单该课程
     * @param $videoId
     * @param $userId
     * @return bool
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function checkCreateOrder($videoId,$userId){
        $info = OnlineVideoModel::where('id',$videoId)
            ->field('id,type,user_ids,checked_phone')
            ->find();
        $info = objToArray($info) ?? [];

        //todo 接口未实现，默认空数组
        $userInfo = [];

        //仅在读学员允许下单
        if($info['type'] == 2){
            //todo 由于接口还没写完，因此这边用变量默认，后面再改
            $isBeStudy = true;  //是否在读学员
            if(!$isBeStudy){
                return false;
            }
        }else if($info['type'] == 3){
            //指定学员可读
            $userIds = !empty($info['user_ids']) ? explode(',',$info['user_ids']) : [];
            //若指定学员字段为空，表示所有人不可下单
            if(empty($userIds) || in_array($userId,$userIds)){
                return false;
            }
        }

        //验证手机号
        if($info['checked_phone'] == 1 && empty($userInfo['mobile'])){
            return false;
        }

        return true;
    }

    /**
     * 获取订单详情
     * @param $orderId
     * @return array
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function getInfo($orderId){
        $info = OnlineVideoOrderModel::where('id',$orderId)->find();

        return objToArray($info) ?? [];
    }

    /**
     * 支付成功，用于支付成功回调用
     * @param $params
     * @return bool
     * @throws DataNotFoundException
     * @throws DbException
     * @throws Exception
     * @throws ModelNotFoundException
     */
    public function payment($params){
        Db::startTrans();
        try {
            // 加锁获取订单信息
            $orderInfo = OnlineVideoOrderModel::where('out_trade_no', $params['out_trade_no'])
                ->field('id,shop_id,status')
                ->lock(true)
                ->find();
            $orderInfo = objToArray($orderInfo) ?? [];
            if (empty($orderInfo)) {
                return false;
            }
            if ($orderInfo['status'] != 1) {
                return false;
            }
            // TODO: 支付回调过来，如果是关闭了的订单，钱要原路退还，不能继续支付流程

            // 修改支付单信息
            $updateInfo = [
                'status' => 2,
                'pay_time' => time(),
                'pay_money' => $params['pay_money'] ?? 0
            ];

            OnlineVideoOrderModel::where('out_trade_no', $params['out_trade_no'])->update($updateInfo);

            //查询主订单ID
            $payLogInfo = PayLogModel::where('controller','online/video_order')
                ->where('order_id',$orderInfo['id'])
                ->where('shop_id',$orderInfo['shop_id'])
                ->field('id,coupon_id')
                ->find();
            $payLogInfo = objToArray($payLogInfo) ?? [];
            if(!empty($payLogInfo)){
                //todo 执行优惠券核销动作，优惠券状态改成已使用等，待接口，后面补上

                //todo 额外数据，用于保存交易单号等信息，由于不知道回调返回的参数，因此这边暂时为空
                $expandData = [
                    'transaction_id' => ''
                ];
                //执行主订单回调
                $this->payLogNotify($payLogInfo['id'],$expandData);
            }

            Db::commit();
            return true;
        } catch (Exception $e) {
            Db::rollback();
            throw $e;
        }
    }

    /**
     * 主订单回调
     * @param $orderId
     * @param null $expandData
     * @return false
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function payLogNotify($orderId,$expandData = null){
        // 加锁获取订单信息
        $orderInfo = PayLogModel::where('id', $orderId)
            ->lock(true)
            ->find();
        $orderInfo = objToArray($orderInfo) ?? [];
        if (empty($orderInfo)) {
            return false;
        }
        if ($orderInfo['status'] != 0) {
            return false;
        }

        // 修改支付单信息
        $updateInfo = [
            'status' => 1,
            'pay_time' => time()
        ];
        $updateInfo = array_merge($expandData,$updateInfo);

        PayLogModel::where('id', $orderId)->update($updateInfo);

        return true;
    }

    /**
     * 根据课程ID获取订单详情
     * @param $shopId
     * @param $videoId
     * @return array
     * @throws DataNotFoundException
     * @throws DbException
     * @throws ModelNotFoundException
     */
    public function getOrderInfoByVideoId($shopId,$videoId): array
    {
        //根据课程id获取订单详情
        $orderInfo = OnlineVideoOrderModel::where('shop_id',$shopId)
            ->where('video_id',$videoId)
            ->field('id,status')
            ->find();
        return objToArray($orderInfo) ?? [];
    }
}
